package com.copa.ums.modules.ums.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.copa.ums.common.api.CommonPage;
import com.copa.ums.common.vo.ResponseVo;
import com.copa.ums.modules.ums.model.*;
import com.copa.ums.modules.ums.mapper.UmsRoleMapper;
import com.copa.ums.modules.ums.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author copa
 * @since 2022-10-31
 */
@Service
public class UmsRoleServiceImpl extends ServiceImpl<UmsRoleMapper, UmsRole> implements UmsRoleService {

    @Resource
    private UmsRoleMapper roleMapper;

    @Resource
    private UmsUserCacheService userCacheService;

    @Resource
    private UmsMenuService menuService;

    @Resource
    private UmsResourceService resourceService;

    @Resource
    private UmsRoleMenuService roleMenuService;

    @Resource
    private UmsRoleResourceService roleResourceService;

    @Override
    public List<UmsRole> getRoleList(Long userId) {
        return roleMapper.getRoleList(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseVo<String> create(UmsRole role) {
        role.setUserCount(0);
        role.setSort(0);
        return save(role)
                ? ResponseVo.success(null)
                : ResponseVo.failed();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseVo<String> delete(List<Long> roleIds) {
        userCacheService.delResourceListByRoleIds(roleIds);
        return removeByIds(roleIds)
                ? ResponseVo.success(null)
                : ResponseVo.failed();
    }

    @Override
    public ResponseVo<CommonPage<UmsRole>> list(String keyword, Integer pageSize, Integer pageNum) {
        Page<UmsRole> page = new Page<>(pageNum, pageSize);
        QueryWrapper<UmsRole> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<UmsRole> lambda = wrapper.lambda();
        if (StrUtil.isNotEmpty(keyword)) {
            lambda.like(UmsRole::getName,keyword);
        }
        return ResponseVo.success(CommonPage.restPage(page(page,wrapper)));
    }

    @Override
    public ResponseVo<List<UmsMenu>> listMenu(Long roleId) {
        return ResponseVo.success(menuService.listMenuByRoleId(roleId));
    }

    @Override
    public ResponseVo<List<UmsResource>> listResource(Long roleId) {
        return ResponseVo.success(resourceService.getResourceListByRoleId(roleId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseVo<Integer> allocMenu(Long roleId, List<Long> menuIds) {
        // 先删除原有关系
        QueryWrapper<UmsRoleMenu> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsRoleMenu::getRoleId, roleId);
        roleMenuService.remove(wrapper);
        // 批量插入新关系
        List<UmsRoleMenu> relationList = new ArrayList<>();
        for (Long menuId : menuIds) {
            UmsRoleMenu relation = new UmsRoleMenu();
            relation.setRoleId(roleId);
            relation.setMenuId(menuId);
            relationList.add(relation);
        }
        roleMenuService.saveBatch(relationList);
        return ResponseVo.success(menuIds.size());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseVo<Integer> allocResource(Long roleId, List<Long> resourceIds) {
        //先删除原有关系
        QueryWrapper<UmsRoleResource> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsRoleResource::getRoleId,roleId);
        roleResourceService.remove(wrapper);
        //批量插入新关系
        List<UmsRoleResource> relationList = new ArrayList<>();
        for (Long resourceId : resourceIds) {
            UmsRoleResource relation = new UmsRoleResource();
            relation.setRoleId(roleId);
            relation.setResourceId(resourceId);
            relationList.add(relation);
        }
        roleResourceService.saveBatch(relationList);
        userCacheService.delResourceListByRoleId(roleId);
        return ResponseVo.success(resourceIds.size());
    }

}
